package mapengine.building
{
import core.Configuration;
import core.manager.BuildingActionManager;
import core.manager.CostManager;
import core.model.GameModel;
import core.model.MapModel;

import eDpLib.events.ProxyEvent;

import flash.display.DisplayObject;
import flash.display.MovieClip;
import flash.errors.IllegalOperationError;

import framework.core.ComponentBuilder;
import framework.core.UIWidget;
import framework.view.components.graphics.SWF;

import isoengine.interfaces.IMapObjectData;

import mapengine.interfaces.IMapBuilding;

import mx.utils.StringUtil;

import values.common.CostValue;
import values.item.BuildingItemValue;
import values.item.BuildingStateValue;
import values.item.ItemValue;
import values.other.GlobalValue;

import view.component.menu.MapBuildingMenu;
import view.component.progressbar.ActionBar;
import view.component.progressbar.IActionBar;
import view.component.tip.MapBuildingTip;
import view.component.window.SpecialFinalBuildUI;

/**
 * MapBuilding
 * @author jliang
 *
 */
public class MapBuilding extends MapObjectBase implements IMapBuilding
{
	//==========================================================================
	//  Constructor
	//==========================================================================
	public function MapBuilding(descriptor:Object=null)
	{
		super(descriptor);
	}
	//==========================================================================
	//  Properties
	//==========================================================================	
    protected function get mapModel():MapModel
    {
        return GameModel.instance.mapModel;
    }
    
	private var vo:BuildingItemValue;
	
	public function get buildingItemValue():BuildingItemValue
	{
		return vo;
	}
	
	public function get constructionData():Object
	{
		return {
			url: Configuration.assetsPath + StringUtil.substitute(String(GlobalValue.staticData.construction_asset_url), vo.width, vo.height),
			classRef: StringUtil.substitute(String(GlobalValue.staticData.construction_asset_classRef), vo.width, vo.height)
		};
	}
	
	public function get needToConstruct():Boolean
	{
		return vo.buildingTemplate.needToConstruct;
	}
	
	public function get isUnderConstruction():Boolean
	{
		return vo.isUnderConstruction;
	}
	
	public function get buildProgress():int
	{
		return vo.buildProgress;
	}
	
	public function get buildCount():int
	{
		return vo.buildCount;
	}
	
	protected function get buildCost():CostValue
	{
		return vo.buildCost;
	}
	
	protected var _isDoingAction:Boolean = false;
	
	public function get isDoingAction():Boolean
	{
		return _isDoingAction;
	}
	
	public function get canUpgrade():Boolean
	{
		return !isDoingAction && !isUnderConstruction && !buildingItemValue.isMaxLevel;
	}
	
	public function get canStash():Boolean
	{
		return !isDoingAction && !isUnderConstruction;
	}
	
	public function get canMove():Boolean
	{
		return !isDoingAction;
	}
	
	public function get canSell():Boolean
	{
		return !isDoingAction;
	}
	
	protected function get actionDefination():Object
	{
		return {
			"0": { state:0, barRef:ActionBar }
		};
	}
	
	protected function get menuReference():Class
	{
		throw new IllegalOperationError("menuReference getter should be overrided.");
	}
	//==========================================================================
	//  Overridden methods: MapObjectBase
	//==========================================================================
	override public function set objectData(value:IMapObjectData):void
	{		
		vo = value as BuildingItemValue;
		
		super.objectData = value;		
	}	
	
	override public function initialize():void
	{
		if (needToConstruct)
		{
			if (isUnderConstruction)
			{
				loadAsset(constructionData.url, constructionAssetLoadedHandler);
				return;
			}
		}
		
		loadAsset(vo.buildingTemplate.assetUrl, assetLoadedHandler);
	}
	
	override public function clickFun():void
	{
		if (isDoingAction) return;
		
		//判断是否是最后一个特殊的建造阶段
		if (isUnderConstruction && buildingItemValue.buildingTemplate.isSpecialFinaBuildCost && buildProgress == buildCount - 1)
		{
			showSpecialFinalBuildUI();
			return;
		}
		
		/*
		if (checkConstructionActionQuene() || checkOtherActionQuene())
		{
			BuildingActionManager.addAction(this, vo.currentState.actionName);
		}
		else
		{
			doOtherClickHandler();
		}
		*/
		doAction();
		
		showMenu();
	}
	
	override protected function outHandler(event:ProxyEvent):void
	{
		super.outHandler(event);
		
		removeTip();
	}
	//==========================================================================
	//  Public methods
	//==========================================================================
	/**
	 * 改变建筑状态 
	 * @param state
	 * @param args
	 * 
	 */	
	public function changeState(state:int, params:Object = null):void
	{
		vo.state = state;
		
		removeSymbol();
		
		//判断是否由建造状态变成下一状态
		if (params == true)
		{
			loadAsset(vo.buildingTemplate.assetUrl, assetLoadedHandler);
		}
        
        checkSymbol();
	}
	
	/**
	 * 进入下一状态 
	 * @param args
	 * 
	 */	
	public function changeToNextState(params:Object = null):void
	{
		changeState(vo.currentState.nextState, params);
	}
	
	/**
	 * 在执行建造动作前 
	 * 
	 */	
	public function beforeBuildAction():Boolean
	{        
		var flag:Boolean = CostManager.hasEnoughToCost(buildCost);
		if (!flag) return false;
		
		CostManager.cost(buildCost);
        
        var tempBuildCost:Object = ItemValue.convertNumbericItemsToServerObject(buildCost.costValueList);
        
        mapModel.buildBuilding(vo, tempBuildCost);
        
		return true;
	}
	
	/**
	 * 在执行建造动作完成后
	 * 
	 */	
	public function finishBuildAction():void
	{
        vo.buildProgress ++;
		
		if (!isUnderConstruction)
		{
			changeToNextState(true);
		}
	}
	
	public function doAction(onStart:Function = null, onComplete:Function = null):void
	{		
		doCurrentStateAction(onStart, onComplete);
	}
	
    public function changeNextDirection():int
    {
        if (asset)
        {
            var allDirection:int = asset.totalFrames - 1;
            
            var temp:int = (direction + 1 > allDirection ? 0 : direction + 1);
            if (temp == direction) return -1;
            direction = temp;
            return direction;
        }
        else
        {
            return -1;
        }
    }
    
	public function enterActionQuene():void
	{
		if (currentAsset) currentAsset.alpha = 0.6;
	}
	
	public function exitActionQuene():void
	{
		if (currentAsset) currentAsset.alpha = 1;
	}
	//==========================================================================
	//  Protected methods
	//==========================================================================
	protected function showMenu():void
	{
		if (isUnderConstruction) return;
		
		var menu:MapBuildingMenu = ComponentBuilder.create(menuReference);
		menu.data = this;
		menu.x = world.view.stage.mouseX;
		menu.y = world.view.stage.mouseY;
		world.view.stage.addChild(menu);
	}
	
	protected function doCurrentStateAction(onStart:Function = null, onComplete:Function = null):void
	{		
		var state:BuildingStateValue = buildingItemValue.currentState;
		
		if (!state.hasAction) return;
		
		var def:Object = actionDefination[state.key];
		
		startAction(def.barRef, state, onStart, onComplete);
	}
	
	protected function checkOtherActionQuene():Boolean
	{
		return false;
	}
	
	protected function checkConstructionActionQuene():Boolean
	{
		if (!isUnderConstruction) return false;
		
		var buildAction:String = buildingItemValue.buildingTemplate.getStateByKey(0).actionName;
		var queneCount:int = BuildingActionManager.getTargetActionQueneCountByAction(this, buildAction);
		var realBuildCount:int = buildCount;
		var finalProgress:int = buildProgress + queneCount;
		
		if (buildingItemValue.buildingTemplate.isSpecialFinaBuildCost)
		{
			realBuildCount --;
		}
		//判断是否已经把所有建造动作排进队列
		return finalProgress < realBuildCount;
	}
	
	protected function startAction(barRef:Class, state:BuildingStateValue, onStart:Function, onComplete:Function):void
	{
		_isDoingAction = true;
		
		var flag:Boolean = true;
		
		if (state.preFunc != null && state.preFunc != "")
		{					
			flag = this[state.preFunc]();			
			if (!flag) 
			{
				actionStartFail(state);
				return;
			}
		}
		
		var actionBar:IActionBar = ComponentBuilder.create(barRef) as IActionBar;
		actionBar.data = { state:state, time:state.actionTime, onStart:onStart, onComplete:onComplete };
		actionBar.onStart = actionStart;
		actionBar.onComplete = actionComplete;
		actionBar.displayObject.name= "actionBar";
		actionBar.displayObject.x = -actionBar.displayObject.width / 2;
		actionBar.displayObject.y = asset.actionBarPos.y;
		
		asset.addChild(actionBar.displayObject);
		
		actionBar.start();
	}
	
	protected function actionStartFail(state:BuildingStateValue):void
	{
		_isDoingAction = false;
	}
	
	protected function actionStart(data:Object):void
	{
		var onStart:Function = data.onStart;
		if (onStart != null)
		{
			onStart();
		}
	}
	
	protected function actionComplete(data:Object):void
	{
		var actionBar:DisplayObject = asset.getChildByName("actionBar");
		if (actionBar)
		{
			if (actionBar.parent)
			{
				actionBar.parent.removeChild(actionBar);
			}
			if (actionBar.hasOwnProperty("dispose"))
			{
				actionBar["dispose"]();
			}
			actionBar = null;
		}
		
		var state:BuildingStateValue = data.state;
		
		if (state.doneFunc != null && state.doneFunc != "")
		{
			this[state.doneFunc]();
		}
		
		var onComplete:Function = data.onComplete;
		
		if (onComplete != null)
		{
			onComplete();
		}
		
		_isDoingAction = false;
	}
	
	protected function doOtherClickHandler():void
	{
		
	}
	
	protected function showSpecialFinalBuildUI():void
	{
		var window:SpecialFinalBuildUI = ComponentBuilder.create(SpecialFinalBuildUI);
		window.data = this;
		window.show();
	}
    
    protected function checkSymbol():void
    {
        
    }
	
	protected function showSymbol(ref:String):void
	{
		removeSymbol();
		
		var symbol:MovieClip = UIWidget.createUI(ref) as MovieClip;
		symbol.name = "symbol";
		symbol.x = asset.symbolPos.x;
		symbol.y = asset.symbolPos.y;
		asset.addChild(symbol);
	}
	
	protected function removeSymbol():void
	{
		var symbol:DisplayObject = asset.getChildByName("symbol");
		if (symbol)
		{
			if (symbol.parent)
			{
				symbol.parent.removeChild(symbol);
			}
		}
	}
	
	protected function showTip(ref:Class):void
	{
		removeTip();
		
		var tip:MapBuildingTip = ComponentBuilder.create(ref) as MapBuildingTip;
		tip.name = "tip";
		tip.data = this;
		tip.y = asset.tipPos.y;
		asset.addChild(tip);
	}
	
	protected function removeTip():void
	{
		var tip:DisplayObject = asset.getChildByName("tip");
		if (tip)
		{
			if (tip.parent)
			{
				tip.parent.removeChild(tip);
			}
			if (tip is MapBuildingTip)
			{
				MapBuildingTip(tip).dispose();
			}
		}
	}
	
	protected function assetReady():void
	{
        checkSymbol();
	}
	//==========================================================================
	//  Event handlers
	//==========================================================================
	protected function constructionAssetLoadedHandler(swf:SWF):void
	{
		var classRef:Class = swf.getClassRef(constructionData.classRef);
		var mc:MovieClip = new classRef() as MovieClip;
		initAsset(mc);
	}
	
	protected function assetLoadedHandler(swf:SWF):void
	{
		var classRef:Class = swf.getClassRef(vo.buildingTemplate.assetClassRef);
		var mc:MovieClip = new classRef() as MovieClip;
		initAsset(mc);
		
		assetReady();
	}
}
}



